<?php
/**
 * Created by PhpStorm.
 * User: longli
 * VX: isa1589518286
 * Date: 2020/12/01
 * Time: 21:09
 * @link http://www.lmterp.cn
 */

namespace app\common\service\system;

use app\common\model\Admin;
use app\common\model\JobApprove;
use app\common\model\JobFlowModule;
use app\common\model\JobFlowSettings;
use app\common\service\BaseService;

/**
 * 审批流验证服务类
 * Class JobFlowService
 * @package app\common\service\system
 */
class ApprovalService extends BaseService
{
    /**
     * 用户
     * @var Admin
     */
    protected $user;

    /**
     * 当前审批节点
     * @var JobFlowSettings
     */
    protected $currentNode;

    /**
     * 最后一个审批流
     * @var JobApprove
     */
    protected $lastJobFlow;

    /**
     * 错误信息
     * @var array
     */
    protected $error = [];

    /**
     * 检查用户是否有权限
     * @param int $flowId 模块配置 id
     * @param int $refId 审批目标 id
     * @return bool
     * @date 2020/12/01
     * @author longli
     */
    public function check($flowId, $refId)
    {
        $this->user = session('lmterp');
        if(empty($this->user)) return false;
        $this->lastJobFlow = $this->getLastJobFlow($flowId, $refId);
        $this->currentNode = $this->getCurrentNode($flowId);
        if(!$this->hasPermissions($this->currentNode))
        {
            $this->error[] = "您没有权限审批";
            return false;
        }
        return true;
    }

    /**
     * 执行审批
     * @param int $flowId 模块配置 id
     * @param int $refId 审批目标 id
     * @param int $status  审批状态
     * @param string $remark 审批备注信息
     * @return bool|JobApprove
     * @date 2020/12/01
     * @author longli
     */
    public function approve($flowId, $refId, $status, $remark = '')
    {
        if(!$this->check($flowId, $refId)) return false;
        if($this->isFinish())
        {
            $this->error[] = "审批已完成";
            return false;
        }
        $next = JobFlowSettings::where([
            "flow_id" => $flowId,
            "node"    => $this->currentNode->node + 1,
        ])->find();

        $jobApp = JobApprove::create([
            'flow_id'       => $flowId,
            'ref_id'        => $refId,
            'id_type'       => $this->currentNode->flow->id_type,
            'status'        => $status,
            'current_name'  => $this->currentNode->name,
            'current_node'  => $this->currentNode->node,
            'next_name'     => $next ? $next->name : '',
            'next_node'     => $next ? $next->node : 0,
            'is_end'        => $status == JobApprove::JOB_STATUS_REJECT ? JobApprove::IS_YES : $this->currentNode->is_end,
            'check_user_id' => $this->user->id,
            'remark'        => $remark,
        ])->refresh();
        \think\facade\Hook::listen('check_status', $jobApp);
        // 如果下一个节点还有权限则自动审核通过
        if($jobApp->is_end != JobApprove::IS_YES && $this->hasPermissions($next))
            return $this->approve($flowId, $refId, $status, $remark);
        return $jobApp;
    }

    /**
     * 获取审批模块配置
     * @param int|string $flowId 模块配置 id 或者模块名称
     * @return JobFlowSettings[]
     * @date 2020/12/01
     * @author longli
     */
    public function getSettings($flowId)
    {
        $module = $this->getModule($flowId);
        return JobFlowSettings::where(['flow_id' => $module->flow_id])->order("node asc")->select();
    }

    /**
     * 获取审批模块
     * @param int|string $flowId 模块配置 id 或者模块名称
     * @return JobFlowModule
     * @date 2020/12/01
     * @author longli
     */
    public function getModule($flowId)
    {
        $jobFlow = JobFlowModule::where("flow_id", $flowId)
            ->whereOr("module", $flowId)->find();
        if(empty($jobFlow)) abort(404, "未配置审批信息，请到系统配置中进行配置");
        return $jobFlow;
    }

    /**
     * 获取最后一条审批流
     * @param int $flowId 模块配置 id
     * @param int $refId 审批目标 id
     * @return JobApprove
     * @date 2020/12/02
     * @author longli
     */
    public function getLastJobFlow($flowId, $refId)
    {
        return $this->lastJobFlow = JobApprove::where(['flow_id' => $flowId, 'ref_id' => $refId])
        ->order("current_node desc")->find();
    }

    /**
     * 获取当前审批流进度
     * @param int $flowId 模块配置 id
     * @param int $refId 审批目标 id
     * @return JobApprove[]
     * @date 2020/12/02
     * @author longli
     */
    public function getJobFlows($flowId, $refId)
    {
        return JobApprove::where(['flow_id' => $flowId, 'ref_id' => $refId])
            ->order("current_node asc")->select();
    }

    /**
     * 判断是否有权限
     * @param JobFlowSettings $node 配置节点
     * @return bool
     * @date 2020/12/01
     * @author longli
     */
    public function hasPermissions($node)
    {
        return $this->user->isSuperAdmin()
            || in_array($this->user->id, explode(',', $node->user_id));
    }

    /**
     * 获取当前审批节点
     * @param int $flowId 模块配置 id
     * @return JobFlowSettings
     * @date 2020/12/01
     * @author longli
     */
    public function getCurrentNode($flowId)
    {
        if($this->lastJobFlow)
        {
            $node = $this->lastJobFlow->is_end == JobApprove::IS_YES ? $this->lastJobFlow->current_node : $this->lastJobFlow->next_node;
            return JobFlowSettings::where(["flow_id" => $flowId, "node" => $node])->find();
        }
        else
        {
            return JobFlowSettings::where("flow_id", $flowId)->order("node asc")->find();
        }
    }

    /**
     * 审批是否完成
     * @return bool
     * @date 2020/12/01
     * @author longli
     */
    public function isFinish()
    {
        return !empty($this->lastJobFlow) &&
            ($this->lastJobFlow->getData('status') == JobApprove::JOB_STATUS_REJECT || $this->lastJobFlow->is_end == JobApprove::IS_YES);
    }

    /**
     * 获取错误信息
     * @return array
     * @date 2020/12/01
     * @author longli
     */
    public function getError()
    {
        return $this->error;
    }

    /**
     * 抄送给用户
     * @param array $userIds 指定用户 ID
     * @date 2020/12/01
     * @author longli
     */
    public function sendTo($userIds = [])
    {
        // @todo
    }
}